package obecto.task.progress
{
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.events.ProgressEvent;
	
	import obecto.task.BaseTask;

	public class ProgressMonitoringTask extends BaseTask implements IProgressiveTask
	{
		public var autoStart : Boolean = true;
		
		private var _progress : Number = 0;
		public function get progress():Number
		{
			return _progress;
		}
		
		private var _progressDispatcher : IEventDispatcher;
		public function set progressDispatcher(value : IEventDispatcher) : void
		{
			if (value != _progressDispatcher)
			{
				if (_progressDispatcher)
				{
					removeProgressDispatcherListeners();
				}
				_progressDispatcher = value;
				if (!_running && _progressDispatcher && autoStart)
				{
					start();
				}
			}
		}
		
		private var _waitComplete : Boolean;
		
		public function ProgressMonitoringTask(progressDispatcher : IEventDispatcher = null, waitComplete : Boolean = true)
		{
			super();
				
			this.progressDispatcher = progressDispatcher;
			_waitComplete = waitComplete;
		}
		
		override protected function startActual() : void
		{
			if (_progressDispatcher)
			{
				addProgressDispatcherListeners();
			}
			else
			{
				complete();	
			}
		}
		
		private function addProgressDispatcherListeners() : void
		{
			_progressDispatcher.addEventListener(Event.COMPLETE, handleLoaderComplete);
			_progressDispatcher.addEventListener(ProgressEvent.PROGRESS, handleLoaderProgress);
		}
		
		private function removeProgressDispatcherListeners() : void
		{
			_progressDispatcher.removeEventListener(Event.COMPLETE, handleLoaderComplete);
			_progressDispatcher.removeEventListener(ProgressEvent.PROGRESS, handleLoaderProgress);			
		}
		
		private function handleLoaderComplete(event : Event) : void
		{
			_progress = 100;
			complete();
		}
		
		private function handleLoaderProgress(event : ProgressEvent) : void
		{
			_progress = (event.bytesLoaded / event.bytesTotal) * 100;
			
			dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, false, _progress, 100));
			
			if (!_waitComplete && _progress == 100)
			{
				complete();
			}
		}
	}
}